/* * Copyright (C) 2016 Baidu, Inc. All Rights Reserved. */ package dodola.anole.lib; import android.content.Context; import android.content.res.AssetManager; import android.util.Log; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import dalvik.system.DexClassLoader; import dodola.anole.runtime.PatchesLoader; import static android.content.Context.MODE_PRIVATE; /** * Created by sunpengfei on 16/9/15. */ public class Anole { private static final String LOG_TAG = "!!Anole!!"; public static void applyPatch(Context context, String dexFile) { try { ClassLoader classLoader = context.getClass().getClassLoader(); String nativeLibraryPath; try { nativeLibraryPath = (String) classLoader.getClass().getMethod("getLdLibraryPath") .invoke(classLoader); } catch (Throwable t) { nativeLibraryPath = getNativeLibraryFolder(context).getPath(); } DexClassLoader dexClassLoader = new DexClassLoader(dexFile, context.getCacheDir().getPath(), nativeLibraryPath, context.getClass().getClassLoader()); // we should transform this process with an interface/impl Class<?> aClass = Class.forName( "dodola.anole.runtime.AppPatchesLoaderImpl", true, dexClassLoader); try { PatchesLoader loader = (PatchesLoader) aClass.newInstance(); String[] getPatchedClasses = (String[]) aClass .getDeclaredMethod("getPatchedClasses").invoke(loader); Log.v(LOG_TAG, "Got the list of classes "); for (String getPatchedClass : getPatchedClasses) { Log.v(LOG_TAG, "class " + getPatchedClass); } if (!loader.load()) { } } catch (Exception e) { e.printStackTrace(); } } catch (Exception ex) { ex.printStackTrace(); } } /** * 从Assets里取出补丁,一般用于测试 * * @param context * @param assetName */ public static String getPathFromAssets(Context context, String assetName) { File dexDir = new File(context.getFilesDir(), "hotfix"); dexDir.mkdirs(); String dexPath = null; try { dexPath = copyAsset(context, assetName, dexDir); } catch (IOException e) { e.printStackTrace(); } return dexPath; } public static String copyAsset(Context context, String assetName, File dir) throws IOException { File outFile = new File(dir, assetName); if (outFile.exists()) { outFile.delete(); } AssetManager assetManager = context.getAssets(); InputStream in = assetManager.open(assetName); OutputStream out = new FileOutputStream(outFile); copyFile(in, out); in.close(); out.close(); return outFile.getAbsolutePath(); } private static void copyFile(InputStream in, OutputStream out) throws IOException { byte[] buffer = new byte[1024]; int read; while ((read = in.read(buffer)) != -1) { out.write(buffer, 0, read); } } private static File getNativeLibraryFolder(Context context) { return context.getDir("lib", MODE_PRIVATE); } }